#pragma once

#include "core/core.h"
#include <driver/dedic_gpio.h>
#include <driver/gpio.h>

#define GPIO_MASK_CACHE 28
/*
typedef struct GPIO_mask
{
    uint8_t GPIO = 0xFF;
    uint32_t mask = 0xFFFFFFFF;
} gpio;
*/

class Planner
{
public:
    // static void set_gpio_mask(uint8_t name, uint32_t mask);
    static uint32_t get_gpio_mask(uint8_t _gpio);
    static void init_gpio();

    static const gpio_num_t sensor_gpio[];
    inline static uint8_t get_gpio_num() {
        return GPIO_MASK_CACHE;
    }
    // static gpio gpio_mask[GPIO_MASK_CACHE];
    // static void GPIO_bundle_init();
    // static dedic_gpio_bundle_handle_t sensor_bundle;
    inline static IRAM_ATTR uint8_t read_GPIO(gpio_num_t num)
    {
        return gpio_get_level(num);
    }
    inline static void set_GPIO(gpio_num_t num, uint8_t vol)
    {
        gpio_set_level(num, vol);
    }
    inline static void set_GPIO_pull(gpio_num_t num, gpio_pull_mode_t up) {
        gpio_set_pull_mode(num, up);
    }
    // 中断设置
    inline static void set_interrupt_gpio(gpio_num_t num, gpio_int_type_t intr_type, gpio_isr_t func, uint8_t flag = 0) {
        gpio_set_intr_type(num, intr_type);
        gpio_install_isr_service(flag);
        gpio_isr_handler_add(num, func, (void*)num);
        gpio_intr_enable(num);
    }
    // 检查当前有多少个物理触摸点被触发
    inline static uint8_t multi_touch(uint32_t sensor)
    {
        uint8_t back = 0;
        for (uint8_t count = 0; count < TOUCH_NUM; count++)
            back += !(sensor & (0b1 << count));
        return back;
    }
    // 检查需要额外触控点位的触摸点
    inline static uint8_t multi_extra_touch(uint32_t sensor)
    {
        uint8_t back = 0;
        for (uint8_t count = 0; count < 8; count++)
            back += !(sensor & (0b1 << (count)));
        return back;
    }
    inline static void minus(int32_t * math, int32_t num) {
        *math -= num;
    }

    inline static void plus(int32_t * math, int32_t num) {
        *math += num;
    }
    /*
    inline static uint8_t get_id(uint8_t _scan, uint32_t gpio, uint8_t multi)
    {
        // 前置条件 已经判定该位点被触摸
        static uint32_t id_pool_map = 0;  // 预分配的ID
        static uint8_t id_pool[20] = {0}; // ID存储池
        uint8_t callback;

        if (!(id_pool_map & (1 << _scan)))
        {
            // 分配新的ID
            for (uint8_t check = 0; check < 20; check++)
            {
                if (!(id_pool_map & (1 << check)))
                {
                    id_pool_map += (1 << check);
                    id_pool[_scan] = check;
                    break;
                }
            }
            callback = id_pool[_scan];
        }
        else
        {
            // 获取原有ID
            callback = id_pool[_scan];
        }

        // 手动释放
        if (!multi)
        {
            if (id_pool_map & (1 << _scan))
                id_pool_map -= (1 << _scan);
        }

        return callback;
    }
    */
};

extern Planner planner;